package com.leetcode.p251300;

import java.util.HashMap;
import java.util.Map;

public class Leetcode0273 {

    public static void main(String[] args) {
        Leetcode0273 leetcode0273 = new Leetcode0273();
        System.out.println(leetcode0273.numberToWords(0));
        System.out.println(leetcode0273.numberToWords(23));
        System.out.println(leetcode0273.numberToWords(30));
        System.out.println(leetcode0273.numberToWords(100));
        System.out.println(leetcode0273.numberToWords(12345));
        System.out.println(leetcode0273.numberToWords(1234567));
        System.out.println(leetcode0273.numberToWords(1234567891));

        System.out.println(leetcode0273.numberToWords(1000).equals("One Thousand"));
        System.out.println(leetcode0273.numberToWords(12345).equals("Twelve Thousand Three Hundred Forty Five"));
        System.out.println(leetcode0273.numberToWords(100000).equals("One Hundred Thousand"));
        System.out.println(leetcode0273.numberToWords(100).equals("One Hundred"));
        System.out.println(leetcode0273.numberToWords(0).equals("Zero"));
    }

    public String numberToWords(int num) {
        Map<Integer, String> numStr = new HashMap<Integer, String>();
        numStr.put(0, "Zero");
        numStr.put(1, "One");
        numStr.put(2, "Two");
        numStr.put(3, "Three");
        numStr.put(4, "Four");
        numStr.put(5, "Five");
        numStr.put(6, "Six");
        numStr.put(7, "Seven");
        numStr.put(8, "Eight");
        numStr.put(9, "Nine");
        numStr.put(10, "Ten");
        numStr.put(11, "Eleven");
        numStr.put(12, "Twelve");
        numStr.put(13, "Thirteen");
        numStr.put(14, "Fourteen");
        numStr.put(15, "Fifteen");
        numStr.put(16, "Sixteen");
        numStr.put(17, "Seventeen");
        numStr.put(18, "Eighteen");
        numStr.put(19, "Nineteen");
        numStr.put(20, "Twenty");
        numStr.put(30, "Thirty");
        numStr.put(40, "Forty");
        numStr.put(50, "Fifty");
        numStr.put(60, "Sixty");
        numStr.put(70, "Seventy");
        numStr.put(80, "Eighty");
        numStr.put(90, "Ninety");
        if (num < 21 || (num/10 < 10 && num %10 ==0)){
            return numStr.get(num);
        }

        int yu = num / 1000000000;
        String re = "";
        if (yu > 0) {
            re = getYu(yu, numStr) + " Billion";
        }
        yu = num % 1000000000 / 1000000;
        if (yu > 0) {
            re += " " + getYu(yu, numStr) + " Million";
        }
        yu = num % 1000000 / 1000;
        if (yu > 0) {
            re += " " + getYu(yu, numStr) + " Thousand";
        }
        yu = num % 1000;
        re += " " + getYu(yu, numStr);
        return re.trim();
    }

    private String getYu(int yu, Map<Integer, String> numStr) {
        StringBuffer sb = new StringBuffer();
        boolean biger100 = yu >= 100;
        if (biger100) {
            sb.append(numStr.get(yu / 100)).append(" Hundred");
        }
        yu = yu % 100;
        if (yu > 0 && biger100) {
            sb.append(" ");
        }

        if (yu > 0 && yu < 21) {
            sb.append(numStr.get(yu));
        } else if (yu > 20 && yu < 100) {
            sb.append(numStr.get(yu / 10 * 10));
            if (yu % 10 != 0) {
                sb.append(" ").append(numStr.get(yu % 10));
            }
        }

        return sb.toString();
    }
}
